<!DOCTYPE html>
<html lang=en

  >

  <head>
    <!-- so meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
    <meta name="description" content="TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？ SPA（ single-page application ）仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成，SPA 不会因为用户的操作而进行页面的重新加载或跳转；取而代之的是利用路由机制实现 HTML 内容的变换，UI 与用户的交互，避免页面的重新加载。  优点：  用户体验好、">
<meta property="og:type" content="article">
<meta property="og:title" content="SPA单界面理解">
<meta property="og:url" content="https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/index.html">
<meta property="og:site_name" content="一个有温度的小流年">
<meta property="og:description" content="TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？ SPA（ single-page application ）仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成，SPA 不会因为用户的操作而进行页面的重新加载或跳转；取而代之的是利用路由机制实现 HTML 内容的变换，UI 与用户的交互，避免页面的重新加载。  优点：  用户体验好、">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2023-09-05T09:31:58.000Z">
<meta property="article:modified_time" content="2023-09-05T11:14:41.379Z">
<meta property="article:author" content="小流年">
<meta name="twitter:card" content="summary">
    
    
      
        
          <link rel="shortcut icon" href="/mrl/images/favicon.ico">
        
      
      
        
          <link rel="icon" type="image/png" href="/mrl/images/favicon-192x192.png" sizes="192x192">
        
      
      
        
          <link rel="apple-touch-icon" sizes="180x180" href="/mrl/images/apple-touch-icon.png">
        
      
    
    <!-- title -->
    <title>SPA单界面理解</title>
    <!-- async scripts -->
    <!-- Google Analytics -->


    <!-- Umami Analytics -->


    <!-- styles -->
    
<link rel="stylesheet" href="/mrl/css/style.css">

    <!-- persian styles -->
    
    <!-- rss -->
    
    
	<!-- mathjax -->
	
<meta name="generator" content="Hexo 6.3.0"></head>


    <body class="max-width mx-auto px3 ltr">
      
        <div id="header-post">
  <a id="menu-icon" href="#" aria-label="Menu"><i class="fa-solid fa-bars fa-lg"></i></a>
  <a id="menu-icon-tablet" href="#" aria-label="Menu"><i class="fa-solid fa-bars fa-lg"></i></a>
  <a id="top-icon-tablet" href="#" aria-label="Top" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fa-solid fa-chevron-up fa-lg"></i></a>
  <span id="menu">
    <span id="nav">
      <ul>
        <!--
       --><li><a href="/mrl/search/">搜索</a></li><!--
     --><!--
       --><li><a href="/mrl/">首页</a></li><!--
     --><!--
       --><li><a href="/mrl/categories/">个人</a></li><!--
     --><!--
       --><li><a href="/mrl/articles/">归档</a></li><!--
     --><!--
       --><li><a href="/mrl/product/">产品</a></li><!--
     -->
      </ul>
    </span>
    <br/>
    <span id="actions">
      <ul>
        
        <li><a class="icon" aria-label="Previous post" href="/mrl/2023/09/05/spring/"><i class="fa-solid fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
        
        
        <li><a class="icon" aria-label="Next post" href="/mrl/2023/09/04/Java%E5%A4%9A%E7%BA%BF%E7%A8%8B%E2%80%93%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"><i class="fa-solid fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
        
        <li><a class="icon" aria-label="Back to top" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fa-solid fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
        <li><a class="icon" aria-label="مشاركة المنشور" href="#"><i class="fa-solid fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
      </ul>
      <span id="i-prev" class="info" style="display:none;">Previous post</span>
      <span id="i-next" class="info" style="display:none;">Next post</span>
      <span id="i-top" class="info" style="display:none;">Back to top</span>
      <span id="i-share" class="info" style="display:none;">مشاركة المنشور</span>
    </span>
    <br/>
    <div id="share" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&text=SPA单界面理解"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&is_video=false&description=SPA单界面理解"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=SPA单界面理解&body=Check out this article: https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/"><i class="fa-solid fa-envelope " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&name=SPA单界面理解&description="><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&t=SPA单界面理解"><i class="fab fa-hacker-news " aria-hidden="true"></i></a></li>
</ul>

    </div>
    
    
      <div id="toc">
        <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-1%EF%BC%9A%E8%AF%B4%E8%AF%B4%E4%BD%A0%E5%AF%B9-SPA-%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%8C%E5%AE%83%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9%E5%88%86%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F"><span class="toc-number">1.</span> <span class="toc-text">TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-2%EF%BC%9Av-show-%E4%B8%8E-v-if-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-number">2.</span> <span class="toc-text">TOP 2：v-show 与 v-if 有什么区别？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-3%EF%BC%9A-Class-%E4%B8%8E-Style-%E5%A6%82%E4%BD%95%E5%8A%A8%E6%80%81%E7%BB%91%E5%AE%9A%EF%BC%9F"><span class="toc-number">3.</span> <span class="toc-text">TOP 3： Class 与 Style 如何动态绑定？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-4%EF%BC%9A-computed-%E5%92%8C-watch-%E7%9A%84%E5%8C%BA%E5%88%AB%E5%92%8C%E8%BF%90%E7%94%A8%E7%9A%84%E5%9C%BA%E6%99%AF%EF%BC%9F"><span class="toc-number">4.</span> <span class="toc-text">TOP 4： computed 和 watch 的区别和运用的场景？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-5%EF%BC%9A%E8%B0%88%E8%B0%88%E4%BD%A0%E5%AF%B9-Vue-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%9F"><span class="toc-number">5.</span> <span class="toc-text">TOP 5：谈谈你对 Vue 生命周期的理解？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-6%EF%BC%9A%E5%9C%A8%E5%93%AA%E4%B8%AA%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%86%85%E8%B0%83%E7%94%A8%E5%BC%82%E6%AD%A5%E8%AF%B7%E6%B1%82%EF%BC%9F"><span class="toc-number">6.</span> <span class="toc-text">TOP 6：在哪个生命周期内调用异步请求？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-7%EF%BC%9Av-model-%E7%9A%84%E5%8E%9F%E7%90%86"><span class="toc-number">7.</span> <span class="toc-text">TOP 7：v-model 的原理</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-8%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9A%84-Web-%E6%8A%80%E6%9C%AF%E7%9A%84%E4%BC%98%E5%8C%96"><span class="toc-number">8.</span> <span class="toc-text">TOP 8：基础的 Web 技术的优化</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-9%EF%BC%9Avue-router%E6%9C%89%E4%B8%A4%E7%A7%8D%E4%BC%A0%E5%8F%82%E6%96%B9%E5%BC%8F"><span class="toc-number">9.</span> <span class="toc-text">TOP 9：vue-router有两种传参方式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-10%EF%BC%9Av-if%E5%92%8Cv-for%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E7%9A%84%E5%BC%8A%E7%AB%AF%E4%BB%A5%E5%8F%8A%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95"><span class="toc-number">10.</span> <span class="toc-text">TOP 10：v-if和v-for一起使用的弊端以及解决办法</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-11%EF%BC%9Avue%E4%B8%AD%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E9%A1%B5%E9%9D%A2%E4%B8%8D%E9%87%8D%E6%96%B0%E6%B8%B2%E6%9F%93%E9%97%AE%E9%A2%98"><span class="toc-number">11.</span> <span class="toc-text">TOP 11：vue中如何解决页面不重新渲染问题</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-12%EF%BC%9A%E8%AF%B4%E4%B8%80%E4%B8%8Bcomputed%E5%92%8Cwatch%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">12.</span> <span class="toc-text">TOP 12：说一下computed和watch的区别</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-13%EF%BC%9Avue%E5%8F%8C%E5%90%91%E7%BB%91%E5%AE%9A%E6%B5%81%E7%A8%8B"><span class="toc-number">13.</span> <span class="toc-text">TOP 13：vue双向绑定流程</span></a></li></ol>
      </div>
    
  </span>
</div>

          
            <div class="content index py4 ">
              
                    <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
  <header>
    
    <h1 class="posttitle p-name" itemprop="name headline">
        SPA单界面理解
    </h1>



    <div class="meta">
      <span class="author p-author h-card" itemprop="author" itemscope itemtype="http://schema.org/Person">
        <span class="p-name" itemprop="name">小流年</span>
      </span>
      
    <div class="postdate">
      
        <time datetime="2023-09-05T09:31:58.000Z" class="dt-published" itemprop="datePublished">2023-09-05</time>
        
      
    </div>


      
    <div class="article-category">
        <i class="fa-solid fa-archive"></i>
        <a class="category-link" href="/mrl/categories/SPA%E5%8D%95%E7%95%8C%E9%9D%A2%E7%90%86%E8%A7%A3/">SPA单界面理解</a>
    </div>


      

    </div>
  </header>
  

  <div class="content e-content" itemprop="articleBody">
    <h1 id="TOP-1：说说你对-SPA-单页面的理解，它的优缺点分别是什么？"><a href="#TOP-1：说说你对-SPA-单页面的理解，它的优缺点分别是什么？" class="headerlink" title="TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？"></a>TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？</h1><ul>
<li><p>SPA（ single-page application ）仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成，SPA 不会因为用户的操作而进行页面的重新加载或跳转；取而代之的是利用路由机制实现 HTML 内容的变换，UI 与用户的交互，避免页面的重新加载。</p>
</li>
<li><p>优点：</p>
</li>
<li><p>用户体验好、快，内容的改变不需要重新加载整个页面，避免了不必要的跳转和重复渲染；</p>
</li>
<li><p>基于上面一点，SPA 相对对服务器压力小；</p>
</li>
<li><p>前后端职责分离，架构清晰，前端进行交互逻辑，后端负责数据处理；</p>
</li>
<li><p>缺点：</p>
</li>
<li><p>初次加载耗时多：为实现单页 Web 应用功能及显示效果，需要在加载页面的时候将 JavaScript、CSS 统一加载，部分页面按需加载；</p>
</li>
<li><p>前进后退路由管理：由于单页应用在一个页面中显示所有的内容，所以不能使用浏览器的前进后退功能，所有的页面切换需要自己建立堆栈管理；</p>
</li>
<li><p>SEO 难度较大：由于所有的内容都在一个页面中动态替换显示，所以在 SEO 上其有着天然的弱势。</p>
</li>
</ul>
<h1 id="TOP-2：v-show-与-v-if-有什么区别？"><a href="#TOP-2：v-show-与-v-if-有什么区别？" class="headerlink" title="TOP 2：v-show 与 v-if 有什么区别？"></a>TOP 2：v-show 与 v-if 有什么区别？</h1><ul>
<li>v-if 是真正的条件渲染，因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建；也是惰性的：如果在初始渲染时条件为假，则什么也不做——直到条件第一次变为真时，才会开始渲染条件块。</li>
<li>v-show 就简单得多——不管初始条件是什么，元素总是会被渲染，并且只是简单地基于 CSS 的 “display” 属性进行切换。<br>所以，v-if 适用于在运行时很少改变条件，不需要频繁切换条件的场景；v-show 则适用于需要非常频繁切换条件的场景。</li>
</ul>
<h1 id="TOP-3：-Class-与-Style-如何动态绑定？"><a href="#TOP-3：-Class-与-Style-如何动态绑定？" class="headerlink" title="TOP 3： Class 与 Style 如何动态绑定？"></a>TOP 3： Class 与 Style 如何动态绑定？</h1><ul>
<li><p>Class 可以通过对象语法和数组语法进行动态绑定：</p>
</li>
<li><p>对象语法</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"> &lt;div v-bind:class=&quot;&#123; active: isActive, &#x27;text-danger&#x27;: hasError &#125;&quot;&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line">data: &#123;</span><br><span class="line">  isActive: true,</span><br><span class="line">  hasError: false</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>数组语法</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  &lt;div v-bind:class=&quot;[isActive ? activeClass : &#x27;&#x27;, errorClass]&quot;&gt;&lt;/div&gt;</span><br><span class="line">data: &#123;</span><br><span class="line">  activeClass: &#x27;active&#x27;,</span><br><span class="line">  errorClass: &#x27;text-danger&#x27;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>Style 也可以通过对象语法和数组语法进行动态绑定：</p>
</li>
<li><p>对象语法</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;div v-bind:style=&quot;&#123; color: activeColor, fontSize: fontSize + &#x27;px&#x27; &#125;&quot;&gt;&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">data: &#123;</span><br><span class="line">  activeColor: &#x27;red&#x27;,</span><br><span class="line">  fontSize: 30</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>数组语法</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;div v-bind:style=&quot;[styleColor, styleSize]&quot;&gt;&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">data: &#123;</span><br><span class="line">  styleColor: &#123;</span><br><span class="line">     color: &#x27;red&#x27;</span><br><span class="line">   &#125;,</span><br><span class="line">  styleSize:&#123;</span><br><span class="line">     fontSize:&#x27;23px&#x27;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
<h1 id="TOP-4：-computed-和-watch-的区别和运用的场景？"><a href="#TOP-4：-computed-和-watch-的区别和运用的场景？" class="headerlink" title="TOP 4： computed 和 watch 的区别和运用的场景？"></a>TOP 4： computed 和 watch 的区别和运用的场景？</h1><ul>
<li><p><strong>computed：</strong> 是计算属性，依赖其它属性值，并且 computed 的值有缓存，只有它依赖的属性值发生改变，下一次获取 computed 的值时才会重新计算 computed 的值；</p>
</li>
<li><p><strong>watch：</strong> 更多的是「观察」的作用，类似于某些数据的监听回调 ，每当监听的数据变化时都会执行回调进行后续操作；</p>
</li>
<li><p>运用场景：</p>
</li>
<li><p>当我们需要进行数值计算，并且依赖于其它数据时，应该使用 computed，因为可以利用 computed 的缓存特性，避免每次获取值时，都要重新计算；</p>
</li>
<li><p>当我们需要在数据变化时执行异步或开销较大的操作时，应该使用 watch，使用 watch 选项允许我们执行异步操作 ( 访问一个 API )，限制我们执行该操作的频率，并在我们得到最终结果前，设置中间状态。这些都是计算属性无法做到的。</p>
</li>
</ul>
<h1 id="TOP-5：谈谈你对-Vue-生命周期的理解？"><a href="#TOP-5：谈谈你对-Vue-生命周期的理解？" class="headerlink" title="TOP 5：谈谈你对 Vue 生命周期的理解？"></a>TOP 5：谈谈你对 Vue 生命周期的理解？</h1><p>（1）生命周期是什么？<br>Vue 实例有一个完整的生命周期，也就是从开始创建、初始化数据、编译模版、挂载 Dom -&gt; 渲染、更新 -&gt; 渲染、卸载等一系列过程，我们称这是 Vue 的生命周期。<br>（2）各个生命周期的作用<br>    - 生命周期描述</p>
<table>
<thead>
<tr>
<th align="center">函数</th>
<th align="center">描述</th>
</tr>
</thead>
<tbody><tr>
<td align="center">beforeCreate</td>
<td align="center">组件实例被创建之初，组件的属性生效之前</td>
</tr>
<tr>
<td align="center">created</td>
<td align="center">组件实例已经完全创建，属性也绑定，但真实 dom 还没有生成，$el 还不可用</td>
</tr>
<tr>
<td align="center">beforeMount</td>
<td align="center">在挂载开始之前被调用：相关的 render 函数首次被调用</td>
</tr>
<tr>
<td align="center">mounted</td>
<td align="center">el 被新创建的 vm.$el 替换，并挂载到实例上去之后调用该钩子</td>
</tr>
<tr>
<td align="center">beforeUpdate</td>
<td align="center">组件数据更新之前调用，发生在虚拟 DOM 打补丁之前</td>
</tr>
<tr>
<td align="center">update</td>
<td align="center">组件数据更新之后</td>
</tr>
<tr>
<td align="center">activited</td>
<td align="center">keep-alive 专属，组件被激活时调用</td>
</tr>
<tr>
<td align="center">deadctivated</td>
<td align="center">keep-alive 专属，组件被销毁时调用</td>
</tr>
<tr>
<td align="center">beforeDestory</td>
<td align="center">组件销毁前调用</td>
</tr>
<tr>
<td align="center">destoryed</td>
<td align="center">组件销毁后调用</td>
</tr>
</tbody></table>
<h1 id="TOP-6：在哪个生命周期内调用异步请求？"><a href="#TOP-6：在哪个生命周期内调用异步请求？" class="headerlink" title="TOP 6：在哪个生命周期内调用异步请求？"></a>TOP 6：在哪个生命周期内调用异步请求？</h1><ul>
<li>可以在钩子函数 created、beforeMount、mounted 中进行调用，因为在这三个钩子函数中，data 已经创建，可以将服务端端返回的数据进行赋值。但是本人推荐在 created 钩子函数中调用异步请求，因为在 created 钩子函数中调用异步请求有以下优点：</li>
<li>能更快获取到服务端数据，减少页面 loading 时间；</li>
<li>ssr 不支持 beforeMount 、mounted 钩子函数，所以放在 created 中有助于一致性；</li>
</ul>
<h1 id="TOP-7：v-model-的原理"><a href="#TOP-7：v-model-的原理" class="headerlink" title="TOP 7：v-model 的原理"></a>TOP 7：v-model 的原理</h1><p>我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定，我们知道 v-model 本质上不过是语法糖，v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件：</p>
<ul>
<li><p>text 和 textarea 元素使用 value 属性和 input 事件；</p>
</li>
<li><p>checkbox 和 radio 使用 checked 属性和 change 事件；</p>
</li>
<li><p>select 字段将 value 作为 prop 并将 change 作为事件。</p>
</li>
<li><p>以 input 表单元素为例：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model=&#x27;something&#x27;&gt;</span><br><span class="line"></span><br><span class="line">相当于</span><br><span class="line"></span><br><span class="line">&lt;input v-bind:value=&quot;something&quot; v-on:input=&quot;something = $event.target.value&quot;&gt;</span><br></pre></td></tr></table></figure></li>
</ul>
<h1 id="TOP-8：基础的-Web-技术的优化"><a href="#TOP-8：基础的-Web-技术的优化" class="headerlink" title="TOP 8：基础的 Web 技术的优化"></a>TOP 8：基础的 Web 技术的优化</h1><ol>
<li>开启 gzip 压缩</li>
<li>浏览器缓存</li>
<li>CDN 的使用 </li>
<li>使用 Chrome Performance 查找性能瓶颈</li>
</ol>
<h1 id="TOP-9：vue-router有两种传参方式"><a href="#TOP-9：vue-router有两种传参方式" class="headerlink" title="TOP 9：vue-router有两种传参方式"></a>TOP 9：vue-router有两种传参方式</h1><p>(1)通过在router.js文件中配置path的地方动态传递参数 eg: path: ‘&#x2F;detail&#x2F;:id’ 然后在组件内通过this.$route.params.id即可获取</p>
<p>(2).在router-link标签中传递参数</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;router -link :to=&#123;</span><br><span class="line">     params:&#123; </span><br><span class="line">     	x:1</span><br><span class="line">     &#125;</span><br><span class="line">    &#125; /&gt;</span><br></pre></td></tr></table></figure>
<ul>
<li>params 传参 : 相当于post请求，页面跳转时参数不会在地址栏中显示</li>
<li>query 传参 : 相当于get请求，页面跳转时参数会在地址栏中显示</li>
<li>也通过this.$route.params获取</li>
<li><strong>注意</strong>：这里通过router-link传递参数的方式是隐式传参</li>
</ul>
<h1 id="TOP-10：v-if和v-for一起使用的弊端以及解决办法"><a href="#TOP-10：v-if和v-for一起使用的弊端以及解决办法" class="headerlink" title="TOP 10：v-if和v-for一起使用的弊端以及解决办法"></a>TOP 10：v-if和v-for一起使用的弊端以及解决办法</h1><ul>
<li>由于v-for的优先级比v-if高，所以导致每循环一次就会去v-if一次，</li>
<li>而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏，所以就会不停的去创建和销毁元素，造成页面卡顿，性能下降。</li>
<li>在vue2中，v-for的优先级高于v-if,把它们放在同一个标签上时，页面每次渲染的时候都会重复的进行判断是十分消耗性能的</li>
<li>解决办法：在v-for的外层或内层包裹一个元素来使用v-if</li>
</ul>
<h1 id="TOP-11：vue中如何解决页面不重新渲染问题"><a href="#TOP-11：vue中如何解决页面不重新渲染问题" class="headerlink" title="TOP 11：vue中如何解决页面不重新渲染问题"></a>TOP 11：vue中如何解决页面不重新渲染问题</h1><p>(1).修改对象属性后页面未重新渲染可以使用 this.$set(对象名称, ‘属性名’, ‘属性值’) (2).使用this.$forceUpdate()方法可重新渲染页面</p>
<ol start="2">
<li>通常是某个渲染的数组改变了层级较深的数据导致页面没有实时渲染</li>
</ol>
<p>就这么写  this.items&#x3D;JSON.parse(JSON.stringify(this.items));</p>
<h1 id="TOP-12：说一下computed和watch的区别"><a href="#TOP-12：说一下computed和watch的区别" class="headerlink" title="TOP 12：说一下computed和watch的区别"></a>TOP 12：说一下computed和watch的区别</h1><ul>
<li>computed是计算属性，它依赖于其他的属性值，当属性值改变的时候，才会重新计算。</li>
<li>watch是监听属性，用来监测自身的属性值，不需要依赖其他属性值。</li>
<li>它们的相同点：都是监听数据变化的。</li>
<li>不同点在于应用场景：computed是用于计算的，适合依赖多个属性值进行计算。</li>
<li>而watch是监听一个属性值，适合用于进行异步操作或者比较大的开销的时候，进行数据监听。比如说设置一个定时器或者监听路由变化这种，这里就需要watch监听，这是computed计算属性没有的。</li>
</ul>
<h1 id="TOP-13：vue双向绑定流程"><a href="#TOP-13：vue双向绑定流程" class="headerlink" title="TOP 13：vue双向绑定流程"></a>TOP 13：vue双向绑定流程</h1><ul>
<li>new Vue()首先执行初始化，对data执行响应话处理，这个过程发生在Observe中。</li>
<li>同时对模板进行编译，找到其中动态绑定数据，从data中获取并初始化试图，这个过程发生在Compile中</li>
<li>同时定义一个更新函数和Watcher，将来对应数据变化时Watcher会调用更新函数。</li>
<li>由于data的某个key在一个视图中可能出现多次，所以每个key都需要一个管家Dep来管理多个Watcher</li>
<li>将来data中数据一旦发生变化，会首先找到对应Dep, 通知所有Watcher执行更新函数。</li>
</ul>

  </div>
</article>



                      
                        <div id="footer-post-container">
  <div id="footer-post">

    <div id="nav-footer" style="display: none">
      <ul>
        
          <li><a href="/mrl/search/">搜索</a></li>
        
          <li><a href="/mrl/">首页</a></li>
        
          <li><a href="/mrl/categories/">个人</a></li>
        
          <li><a href="/mrl/articles/">归档</a></li>
        
          <li><a href="/mrl/product/">产品</a></li>
        
      </ul>
    </div>

    
    
      <div id="toc-footer" style="display: none">
        <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-1%EF%BC%9A%E8%AF%B4%E8%AF%B4%E4%BD%A0%E5%AF%B9-SPA-%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%8C%E5%AE%83%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9%E5%88%86%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F"><span class="toc-number">1.</span> <span class="toc-text">TOP 1：说说你对 SPA 单页面的理解，它的优缺点分别是什么？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-2%EF%BC%9Av-show-%E4%B8%8E-v-if-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-number">2.</span> <span class="toc-text">TOP 2：v-show 与 v-if 有什么区别？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-3%EF%BC%9A-Class-%E4%B8%8E-Style-%E5%A6%82%E4%BD%95%E5%8A%A8%E6%80%81%E7%BB%91%E5%AE%9A%EF%BC%9F"><span class="toc-number">3.</span> <span class="toc-text">TOP 3： Class 与 Style 如何动态绑定？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-4%EF%BC%9A-computed-%E5%92%8C-watch-%E7%9A%84%E5%8C%BA%E5%88%AB%E5%92%8C%E8%BF%90%E7%94%A8%E7%9A%84%E5%9C%BA%E6%99%AF%EF%BC%9F"><span class="toc-number">4.</span> <span class="toc-text">TOP 4： computed 和 watch 的区别和运用的场景？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-5%EF%BC%9A%E8%B0%88%E8%B0%88%E4%BD%A0%E5%AF%B9-Vue-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E7%90%86%E8%A7%A3%EF%BC%9F"><span class="toc-number">5.</span> <span class="toc-text">TOP 5：谈谈你对 Vue 生命周期的理解？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-6%EF%BC%9A%E5%9C%A8%E5%93%AA%E4%B8%AA%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%86%85%E8%B0%83%E7%94%A8%E5%BC%82%E6%AD%A5%E8%AF%B7%E6%B1%82%EF%BC%9F"><span class="toc-number">6.</span> <span class="toc-text">TOP 6：在哪个生命周期内调用异步请求？</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-7%EF%BC%9Av-model-%E7%9A%84%E5%8E%9F%E7%90%86"><span class="toc-number">7.</span> <span class="toc-text">TOP 7：v-model 的原理</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-8%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9A%84-Web-%E6%8A%80%E6%9C%AF%E7%9A%84%E4%BC%98%E5%8C%96"><span class="toc-number">8.</span> <span class="toc-text">TOP 8：基础的 Web 技术的优化</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-9%EF%BC%9Avue-router%E6%9C%89%E4%B8%A4%E7%A7%8D%E4%BC%A0%E5%8F%82%E6%96%B9%E5%BC%8F"><span class="toc-number">9.</span> <span class="toc-text">TOP 9：vue-router有两种传参方式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-10%EF%BC%9Av-if%E5%92%8Cv-for%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E7%9A%84%E5%BC%8A%E7%AB%AF%E4%BB%A5%E5%8F%8A%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95"><span class="toc-number">10.</span> <span class="toc-text">TOP 10：v-if和v-for一起使用的弊端以及解决办法</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-11%EF%BC%9Avue%E4%B8%AD%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E9%A1%B5%E9%9D%A2%E4%B8%8D%E9%87%8D%E6%96%B0%E6%B8%B2%E6%9F%93%E9%97%AE%E9%A2%98"><span class="toc-number">11.</span> <span class="toc-text">TOP 11：vue中如何解决页面不重新渲染问题</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-12%EF%BC%9A%E8%AF%B4%E4%B8%80%E4%B8%8Bcomputed%E5%92%8Cwatch%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">12.</span> <span class="toc-text">TOP 12：说一下computed和watch的区别</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TOP-13%EF%BC%9Avue%E5%8F%8C%E5%90%91%E7%BB%91%E5%AE%9A%E6%B5%81%E7%A8%8B"><span class="toc-number">13.</span> <span class="toc-text">TOP 13：vue双向绑定流程</span></a></li></ol>
      </div>
    

    <div id="share-footer" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&text=SPA单界面理解"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&is_video=false&description=SPA单界面理解"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=SPA单界面理解&body=Check out this article: https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/"><i class="fa-solid fa-envelope fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&title=SPA单界面理解"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&name=SPA单界面理解&description="><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://liushuaijun.gitee.io/mrl/2023/09/05/%E5%AF%B9SPA%E5%8D%95%E9%A1%B5%E9%9D%A2%E7%9A%84%E7%90%86%E8%A7%A3/&t=SPA单界面理解"><i class="fab fa-hacker-news fa-lg" aria-hidden="true"></i></a></li>
</ul>

    </div>

    <div id="actions-footer">
        <a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fa-solid fa-bars fa-lg" aria-hidden="true"></i> Menu</a>
        
          <a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fa-solid fa-list fa-lg" aria-hidden="true"></i> TOC</a>
        
        <a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fa-solid fa-share-alt fa-lg" aria-hidden="true"></i> Share</a>
        <a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fa-solid fa-chevron-up fa-lg" aria-hidden="true"></i> Top</a>
    </div>

  </div>
</div>

                          
                            <footer id="footer">
  <div class="footer-left">
    Copyright &copy;
    
    
    2020-2023
    小流年
  </div>
  <div class="footer-right">
    <nav>
      <ul>
        <!--
       --><li><a href="/mrl/search/">搜索</a></li><!--
     --><!--
       --><li><a href="/mrl/">首页</a></li><!--
     --><!--
       --><li><a href="/mrl/categories/">个人</a></li><!--
     --><!--
       --><li><a href="/mrl/articles/">归档</a></li><!--
     --><!--
       --><li><a href="/mrl/product/">产品</a></li><!--
     -->
      </ul>
    </nav>
  </div>
  
  <div class="busuanzi">
    
      <!-- 不蒜子统计 -->
      <span id="busuanzi_container_site_pv">
        网站总访问量:<span id="busuanzi_value_site_pv"></span>
      </span>
      
     <span class="post-meta-divider">|</span>
      <span id="busuanzi_container_site_uv" style='display:none'>
          本站访客数<span id="busuanzi_value_site_uv"></span>人
      </span>
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
     
  </div>
</footer>

            </div>
            <!-- styles -->



  <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'"/>


              <!-- jquery -->

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>




<!-- clipboard -->

  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" crossorigin="anonymous"></script>
  
  <script type="text/javascript">
  $(function() {
    // copy-btn HTML
    var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"Copy to clipboard!\">";
    btn += '<i class="fa-regular fa-clone"></i>';
    btn += '</span>';
    // mount it!
    $(".highlight table").before(btn);
    var clip = new ClipboardJS('.btn-copy', {
      text: function(trigger) {
        return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str,it)=>str+it.innerText+'\n','')
      }
    });
    clip.on('success', function(e) {
      e.trigger.setAttribute('aria-label', "Copied!");
      e.clearSelection();
    })
  })
  </script>


<script src="/mrl/js/main.js"></script>

<!-- search -->

<!-- Baidu Analytics -->

<!-- Cloudflare Analytics -->

<!-- Disqus Comments -->

<!-- utterances Comments -->

    </body>

    </html>